﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Shared.Method;
using Shared.Model;
using Client;
using StationTestDll;
using System.Threading;
using System.Threading.Tasks;
using System.IO.Ports;
using Shared.SoftMethod;

namespace ModemWrite
{
    public partial class FormRealWriteScan : UserControl
    {
        public static readonly byte[] OPEN_MODEM = { 0x07, 0xC6, 0x04, 0x08, 0x00, 0x8A, 0x08, 0xFE, 0x95 };
        public static readonly byte[] SCAN = { 0x04, 0xE4, 0x04, 0x00, 0xFF, 0x14 };
        public static readonly byte[] SCAN_ACK = { 0x04, 0xD0, 0x00, 0x00, 0xFF, 0x2C };

        public static readonly byte[] SCAN2 = { 0x1B, 0x31 };
        public static readonly byte[] SCAN2_ACK = { 0x06 };

        private string _stationIp = null;

        private string _localIp = null;
        private int _localPort = 0;

        private string _modemIp = null;
        private string _modemUser = null;
        private string _modemPwd = null;

        private int _myFormNum = 0;

        //private YcdTelnetSecond _telnet = null;
        private string _defaultSn = null;

        //增加一个事件传递正在写入信息的指令
        public event Action<int> OnWrite;
        public event Action<string, int> OnEndAndWrite;

        private List<string> _listLog = new List<string>();

        //所有的产品类型信息
        private List<Device_Type> _listType = null;

        //private FLOW _firstFlow = null;
        //private long _nodeId = 0;

        //保存操作的TASK
        //private CancellationTokenSource _tokenTag = null;
        private Thread _writeThread = null;


        //private string _writeBob = null;

        //串口名称
        private string _serialPortName = null;

        //串口
        private SerialPort _serial = null;

        private byte[] _sendCodes;
        private byte[] _recvCodes;

        private string _cmdChoice = null;


        //获取初始化数据
        public FormRealWriteScan(string localIp, int localPort,
            string modemIp, string modemUser, string modemPwd,
            int formNum, List<Device_Type> listType,
            string defaultSn, string stationIp = "127.0.0.1",
            string writeBob=null)
        {
            _stationIp = stationIp;

            _localIp = localIp;
            _localPort = localPort;

            _modemIp = modemIp;
            _modemUser = modemUser;
            _modemPwd = modemPwd;

            _myFormNum = formNum;

            _defaultSn = defaultSn;

            _listType = listType;


            //_writeBob = writeBob;

            _serialPortName = AppSetting.GetValue("ComName" + _myFormNum);

            string scanRule = AppSetting.GetValue("ScanRule");

            _cmdChoice = AppSetting.GetValue("CmdChoice");

            if (scanRule == "0")
            {
                _sendCodes = SCAN;
                _recvCodes = SCAN_ACK;
            }
            else if (scanRule == "1")
            {
                _sendCodes = SCAN2;
                _recvCodes = SCAN2_ACK;
            }

            if (string.IsNullOrEmpty(localIp)
                || string.IsNullOrEmpty(modemIp)
                || string.IsNullOrEmpty(modemUser)
                || string.IsNullOrEmpty(modemPwd)
                || localPort <= 1024)
            {
                //初始化的参数不正确
                MessageBox.Show(string.Format("窗口：{0}，初始化参数不正确", _myFormNum));
                this.Dispose();//销毁窗口
            }
            InitializeComponent();
        }

        private void FormRealWrite_Load(object sender, EventArgs e)
        {
            //从APPCONFIG获取配置
            //string nodeId = AppSetting.GetValue("StationNodeId");
            //if (string.IsNullOrEmpty(nodeId) == false) long.TryParse(nodeId, out _nodeId);

            string msg;
            //获取串口连接
            _serial = PortBaseClass.GetNewSerialPort(9600, _serialPortName, 8, out msg);

            if (_serial == null || _serial.IsOpen == false)
            {
                SoftShared.AppendText(this, this.richTextBoxMsg, "获取串口连接失败,串口号：" + _serialPortName);
                SoftShared.AppendText(this, this.richTextBoxMsg, msg);
                return;
            }

            #region 自动化扫描方案
            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    BindAndWrite();
                }
            });
            #endregion
        }

        private void TextBoxXponSn_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (this.textBoxXponSn.ReadOnly) return;
            //只能输入16进制数字和回车符号'\r'或者'\n'，MAC地址中的字符只能位0-9,A~Z
            if (e.KeyChar == '\n' || e.KeyChar == '\r')
            {
                e.Handled = true;
                //TestStart();
                if (this.textBoxXponSn.Text.Trim().Length != 12)
                {
                    AppendRichTextBox("BOSA_SN地址不为12位数");
                    this.textBoxXponSn.Clear();
                    this.textBoxXponSn.Focus();
                }
                else
                {
                    //Action d = new Action(BindAndWrite);
                    //d.BeginInvoke(null, null);
                    this.textBoxXponSn.ReadOnly = true;

                    ////给外部调用的END AND WRITE
                    //_tokenTag?.Cancel();//终止线程    
                    //_tokenTag?.Dispose();
                    //_tokenTag = new CancellationTokenSource();

                    //Task.Factory.StartNew(() =>
                    // {
                    //     BindAndWrite();
                    // }, _tokenTag.Token);

                    //终止线程
                    //_cancell.Cancel();

                    _writeThread?.Abort();
                    //_writeThread?.Join();
                    _writeThread = new Thread(new ThreadStart(()=>
                    {
                        BindAndWrite();
                    }));

                    _writeThread.Start();
                }
            }
            else if ((e.KeyChar >= 'a' && e.KeyChar <= 'z')
                || (e.KeyChar >= 'A' && e.KeyChar <= 'Z')
                || (e.KeyChar >= '0' && e.KeyChar <= '9')
                || (e.KeyChar == 8))
            {
                //判断是否位16进制字符，将小写全部转为大写
                e.Handled = false;
            }
            else
            {
                MessageBox.Show("只能输入数字和A-Z");
                e.Handled = true;
            }
        }

        //终止正在运行中的线程，开始新的线程
        public void EndAndWrite(string xponSn)
        {
            //给外部调用的END AND WRITE
            //_tokenTag?.Cancel();//终止线程    
            //_tokenTag?.Dispose();
            //_tokenTag = new CancellationTokenSource();

            SetControlText(this.textBoxXponSn, xponSn);
            //this.textBoxXponSn.Text = xponSn;

            //Task.Factory.StartNew(() =>
            //{
            //    BindAndWrite();
            //}, _tokenTag.Token);


            _writeThread?.Abort();
            //_writeThread?.Join();
            _writeThread = new Thread(new ThreadStart(() =>
            {
                BindAndWrite();
            }));

            _writeThread.Start();
        }

        //绑定mac和sn
        private void BindAndWrite()
        {
            //SetTextBoxEnable(textBoxXponSn, false);
            WaitForModemExit();

            //ClearText(this.richTextBoxMsg);

            //some tips 
            SoftShared.SetControl(this, this.textBoxMacAddr, string.Empty);
            SoftShared.SetControl(this, this.labelTestResult, "放入主板");
            SoftShared.SetControl(this, this.richTextBoxMsg, "20秒后，运行扫描\r\n");

            OnWrite?.Invoke(_myFormNum);//发送正在写入信息的指令

            _listLog.Clear();

            Thread.Sleep(20000);//sleep 20 second

            //get xpon sn from scan machine
            string xponSn = PortBaseClass.ScanControl(_serial, _serialPortName, _sendCodes, _recvCodes);
            //if (string.IsNullOrEmpty(xponSn))
            //    xponSn = PortBaseClass.ScanControl(_serial, _serialPortName, _sendCodes, _recvCodes);

            if (string.IsNullOrEmpty(xponSn))
            {
                AppendRichTextBox("扫描失败");
                FinallyDone();

                MacFocus(true);

                return;
            }
            else
            {
                SoftShared.SetControl(this, this.textBoxXponSn, xponSn);
            }

            bool rescan = false;

            //通过PING和ARP获得产品MAC地址
            //PING测试
            int pingOkTimes = 0;
            for (int i = 0; i < 60; i++)
            {
                if (PingBaseClass.PingTest(_localIp, _modemIp))
                {
                    pingOkTimes++;
                    if (pingOkTimes >= 4)
                    {
                        if (i > 25) rescan = true;
                        AppendRichTextBox($"ping times is:{i}");
                        break;
                    }
                }
                else
                {
                    pingOkTimes = 0;
                }

                Thread.Sleep(500);
            }

            if (pingOkTimes < 4)
            {
                //WriteLog("未能成功PING通光猫");
                AppendRichTextBox("未能成功PING通光猫");

                //FinallyDone(xponSn);
                MacFocus(true);
                return;
            }

            if (rescan)
            {
                xponSn = PortBaseClass.ScanControl(_serial, _serialPortName, _sendCodes, _recvCodes);
                SoftShared.SetControl(this, this.textBoxXponSn, xponSn);
            }

            //string xponSn = this.textBoxXponSn.Text.Trim();
            string msg = null;

            if (_serial == null || _serial.IsOpen == false) _serial = PortBaseClass.GetNewSerialPort(9600, _serialPortName, 8, out msg);
            if (_serial == null) return;

#if false
            string xponSn = PortBaseClass.ScanControl(_serial, _serialPortName,_sendCodes,_recvCodes);
            if (string.IsNullOrEmpty(xponSn))
                xponSn = PortBaseClass.ScanControl(_serial, _serialPortName, _sendCodes, _recvCodes);


            //AppendRichTextBox(xponSn);

            if (string.IsNullOrEmpty(xponSn))
            {
                AppendRichTextBox("扫描失败");
                FinallyDone();

                MacFocus(true);

                return;
            }
            else
            {
                SoftShared.SetControl(this, this.textBoxXponSn, xponSn);
            }
#endif

            YCD_DEVICE ycdW = new YCD_DEVICE();//查询YCDDEVICE的类

            //判断此MAC地址是否已经存在了
            if (PublicData.ListAddress.ContainsKey(xponSn))
            {
                AppendRichTextBox("此MAC地址正在其他窗口使用，请勿重复扫描");

                if (PublicData.ListAddress.TryGetValue(xponSn, out int formNum))
                {
                    string enterBosa = (string)this.Invoke(PublicData.enterMsgDelegate, formNum, "BOSA SN");

                    if (enterBosa != xponSn)
                    {
                        //清除BOSA对应的DICT
                        PublicData.ListAddress.Remove(xponSn);

                        //解绑BOSA与YCD_MAC
                        ycdW.Clear();
                        ycdW.SetWhere(string.Format("LIGHT_MODULE_SN='{0}'", xponSn));
                        ycdW.SetUpdate();
                        ycdW.LIGHT_MODULE_SN = null;
                        MethodWcf.UpdateYcdDeviceClient(ycdW);

                        //写新的信息
                        OnEndAndWrite?.BeginInvoke(enterBosa, formNum, null, null);
                    }
                }

                FinallyDone();

                MacFocus(true);

                return;
            }
            else
            {
                PublicData.ListAddress.Add(xponSn, _myFormNum);
            }

            //bool isBinding = false;
            string productMac = null;//产品MAC地址

//#if false //when rescan xpon sn, redistribute mac

            ycdW.SetWhere();
            ycdW.LIGHT_MODULE_SN = xponSn;
            var selectYcdDevice = MethodWcf.SelectYcdDeviceClient(ycdW);

            if (selectYcdDevice.result)//SN已经绑定过MAC地址
            {
                //isBinding = true;
                //在友创达Mac地址中如果查找到对应的MAC地址，则找到对应的device_data
                productMac = selectYcdDevice.value[0].YCD_MAC;

                //修改此MAC的站位信息，当站位不为当前站位时修改
                //修改站位不成功，说明此BOSA对应的YCD_MAC已经被另外一个光猫使用了，此BOSA必须绑定新的YCD_MAC
                //能够防止不需要绑定的BOSA获取新的MAC地址
                //如果出现扫描BOSA重号的，可能会导致已经到了包装的产品信息被清空
                //string sqlW = string.Format("YCD_MAC='{0}' and (select COUNT(*) from PRODUCT where YCD_MAC='{0}' and (MAC is  null or MAC='' or MAC='{1}' or YCD_MAC='{1}'))=1", productMac, modemMac);
                string sqlW = string.Format("YCD_MAC='{0}' and (select COUNT(*) from PRODUCT where YCD_MAC='{0}' and (MAC is  null or MAC=''))=1", productMac);

                //在线返工使用的SQL语句,BOB定制版专用
                //string sqlW = string.Format("YCD_MAC='{0}'", productMac);

                PRODUCT proU = new PRODUCT();
                proU.SetWhere(sqlW);
                proU.SetUpdate();
                proU.NODE_ID = 20063;
                proU.LINE_ID = 5016;
                proU.FLOW_ID = 117;
                proU.STATE = false;
                proU.NODE_STATE = true;

                var update = MethodWcf.UpdateProductClient(proU);
                if (update.result)
                    AppendRichTextBox("修改站位成功");
                else
                {
                    AppendRichTextBox("修改站位失败，绑定新的内部MAC地址");

                    //解绑BOSA与YCD_MAC
                    ycdW.Clear();
                    ycdW.SetWhere();
                    ycdW.YCD_MAC = selectYcdDevice.value[0].YCD_MAC;
                    ycdW.SetUpdate();
                    ycdW.LIGHT_MODULE_SN = "";
                    MethodWcf.UpdateYcdDeviceClient(ycdW);

                    //获取新的YCD_MAC
                    productMac = MethodWcf.GetYcdMacClient(selectYcdDevice.value[0].PON_TYPE);

                    //绑定BOSA与YCD_MAC
                    ycdW.Clear();
                    ycdW.SetWhere();
                    ycdW.YCD_MAC = productMac;
                    ycdW.SetUpdate();
                    ycdW.LIGHT_MODULE_SN = xponSn;

                    var updateYcdDevice = MethodWcf.UpdateYcdDeviceClient(ycdW);
                    if (updateYcdDevice.result == false)
                    {
                        AppendRichTextBox("绑定BOSA和MAC失败");

                        FinallyDone(xponSn);
                        return;
                    }
                    AppendRichTextBox(string.Format("绑定成功，MAC[{0}]，XponSn[{1}]", productMac, xponSn));
                }
            }
            else
//#endif
            {
                //到数据中查找XPON SN是否存在
                BOSA_DATA bosaW = new BOSA_DATA();
                bosaW.SetWhere();
                bosaW.SN = xponSn;
                //bosaW.DeviceType = selectDevice.value[0].PONType;//ADD_18.2.1，确保BOSA与MAC的BOSA类型一致
                var selectBosa = MethodWcf.SelectBosaDataClient(bosaW);

                if (selectBosa.result == false)
                {
                    AppendRichTextBox("未能获得BOSA数据，绑定失败");

                    //删除相关的MAC信息
                    FinallyDone(xponSn);
                    return;
                }

                productMac = MethodWcf.GetYcdMacClient(selectBosa.value[0].DeviceType);

                //LogHelper.WriteDebugLogTxt("BINDING",string.Format( "绑定MAC[{0}]与SN[{1}]失败", productMac,xponSn));

                //绑定SN和MAC
                ycdW.Clear();
                ycdW.SetWhere();
                ycdW.YCD_MAC = productMac;
                ycdW.SetUpdate();
                ycdW.LIGHT_MODULE_SN = xponSn;

                var updateYcdDevice = MethodWcf.UpdateYcdDeviceClient(ycdW);
                if (updateYcdDevice.result == false)
                {
                    AppendRichTextBox("绑定BOSA和MAC失败");

                    FinallyDone(xponSn);
                    return;
                }

                AppendRichTextBox(string.Format("绑定成功，MAC[{0}]，XponSn[{1}]", productMac, xponSn));
            }

            if (string.IsNullOrEmpty(productMac))
            {
                AppendRichTextBox("未能获得内部MAC地址，绑定失败");

                FinallyDone(xponSn);
                return;
            }

            //显示MAC地址
            SetControlText(this.textBoxMacAddr, productMac);

            //判断MAC是否可以进行此工序
            //string msg = null;
            bool canTest = StationTest.IfCanTest(productMac, ref msg, _stationIp);

            //WriteLog(msg);
            AppendRichTextBox(msg);

            if (canTest == false)
            {
                AppendRichTextBox("测试申请失败！");
                //删除相关的MAC信息
                FinallyDone(xponSn);
                return;
            }

            //获取deviceData
            Device_Data deviceW = new Device_Data();
            deviceW.SetWhere(string.Format("ID=(select DEVICE_DATA_ID from YCD_DEVICE where YCD_MAC='{0}')", productMac));

            var selectDevice = MethodWcf.SelectDeviceDataClient(deviceW);
            if (selectDevice.result == false)
            {
                AppendRichTextBox("未能获取Device_Data的数据");
                FinallyDone(xponSn);
                return;
            }

            //信息写入的部分
            selectDevice.value[0].LightModuleSN = xponSn;//增加xponSN信息
            selectDevice.value[0].MACAddr = productMac;//增加MAC信息

            //写信息的部分
            var writeResult = ModemMsgWrite(selectDevice.value[0]);

            //获取所有log信息
            string log = GetListLog();

            //写LOG信息
            bool saveLogResult = StationTest.SaveTestData(productMac, writeResult, log, ref msg, _stationIp);
            AppendRichTextBox(string.Format("写LOG信息结果为：{0}，返回信息为：{1}", saveLogResult, msg));

            AppendRichTextBox("信息写入工作完成");


            if (selectDevice.value[0].PONType == "EPON")
                FinallyDone(xponSn, writeResult && saveLogResult, "E");
            else
                FinallyDone(xponSn, writeResult && saveLogResult, "G");

            return;
        }

        private void WaitForModemExit()
        {
            //判断光猫断开连接
            SoftShared.AppendText(this, this.richTextBoxMsg, "断开光猫");

            while (PingBaseClass.PingTest(_localIp, _modemIp) == true) System.Threading.Thread.Sleep(2000);
        }

        private void SetControlText(Control control, string strText)
        {
            if (this.InvokeRequired)
            {
                Action<Control, string> d = new Action<Control, string>(SetControlText);
                Invoke(d, control, strText);
            }
            else
            {
                lock (PublicData.LOCKOBJUI)
                    control.Text = strText;
            }
        }

        //信息写入
        private bool ModemMsgWrite(Device_Data deviceData)
        {
            //获取产品型号的相关数据
            var deviceType = GetDeviceType(deviceData.DeviceType, deviceData.HW_PROVINCE_NAME);

            if (deviceType == null)
            {
                //WriteLog("未能获取产品的类型信息");
                AppendRichTextBox("未能获取产品的类型信息");

                //FinallyDone(deviceData.MACAddr);
                return false;
            }

            //判断DEVICE DATA与TYPE的不同之处
            if ((deviceType.XPONMode == "EPON" && deviceData.PONType != "EPON")
                || (deviceType.XPONMode == "GPON" && deviceData.PONType != "STIA"))
            {
                //WriteLog("产品信息与类型信息不符合，请检查数据正确性");
                AppendRichTextBox("产品信息与类型信息不符合，请检查数据正确性");


                //FinallyDone(deviceData.MACAddr);
                return false;
            }

            //SetTestResult(true, "WAITFOR");
            //if (deviceData.PONType == "EPON")
            //{
            //    SetControlText(this.labelTestResult, "EPON", Color.Blue);
            //}
            //else
            //{
            //    SetControlText(this.labelTestResult, "GPON", Color.BlueViolet);
            //}
            SetControlText(this.labelTestResult, "WAITFOR", Color.Black);

            ////初始化telnet
            YcdTelnetSecond tel = null;
            for (int i = 0; i < 3; i++)
            {
                ////初始化telnet
                //tel = TelnetModem();
                if (_portOffset >= 800) _portOffset = 0;
                _portOffset++;

                tel = YcdTelnetMethod.TelnetModem(_localIp, _modemIp, _localPort + _portOffset, 23, _modemUser, _modemPwd);


                if (tel == null)
                {
                    //WriteLog("TELNET光猫失败");
                    AppendRichTextBox("TELNET光猫失败");
                }
                else
                {
                    break;
                }

                Thread.Sleep(2000);
            }

            if (tel == null)
            {
                //FinallyDone(deviceData.MACAddr);
                return false;
            }

            //显示正在测试当中
            //SetTestResult(false, "TESTING");
            SetControlText(this.labelTestResult, "TESTING", Color.Black);


            //判断是MTK还是R方案
            bool writeResult = false;

            //R方案的EPON和GPON
            writeResult = WriteDeviceDataR(deviceData, deviceType, tel);

            // if (writeResult)
            // {
                // writeResult = TestButton(tel);
            // }

            //关闭socket
            tel.Send("exit");
            tel.Close();

            //等待2秒
            Thread.Sleep(2000);

            return writeResult;
        }

        private string GetListLog()
        {
            StringBuilder allLog = new StringBuilder();
            for (int i = 0; i < _listLog.Count; i++)
            {
                allLog.Append(_listLog[i] + "\r\n");
            }
            return allLog.ToString();
        }

        private bool TestButton(YcdTelnetSecond tel)
        {
            string keyWps = string.Empty;
            bool ret = false;


            if (tel.SendAndRecv("cat /etc/swver", "Compile", out string message) == true)
            {
                if (message.Contains("_CU"))
                {
                    SetControlText(this.labelTestResult, "请按WPS按键");

                    ret = TelnetSendAndRecv(tel, "cat /proc/kmsg & led test start", "#");
                    keyWps = "led button";
                }
                else if (message.Contains("CMCC"))
                {
                    //临时添加指令到信息写入软件
                    //TelnetSendAndRecv(tel, "prolinecmd i2c set 51 7f-7f 03", "set dev:0x51 reg:0x7f-0x7f 03");
                    //TelnetSendAndRecv(tel, "prolinecmd i2c set 51 9d-9d 40", "set dev:0x51 reg:0x9d-0x9d 40");
                    //TelnetSendAndRecv(tel, "prolinecmd i2c set 51 db-db 3e", "set dev:0x51 reg:0xdb-0xdb 3e");

                    TelnetSendAndRecv(tel, "flash set ATM_VC_TBL.0.itfGroup 31", "itfGroup=31");

                    SetControlText(this.labelTestResult, "请按WPS按键");

                    //执行一条让WIFI关闭的指令
                    TelnetSendAndRecv(tel, "flash set USER_FACTORY_MODE 1", "USER_FACTORY_MODE=1");

                    //tel.SendAndRecv("killall -9 lanNetInfo", "#",out message);
                    //执行一条写入MAC后不断开TELNET的指令
                    TelnetSendAndRecv(tel, "killall -9 lanNetInfo", "#");

                    ret = TelnetSendAndRecv(tel, "cat /proc/kmsg & led test start", "#");
                    keyWps = "wps button";
                }
            }
            else
            {
                AppendRichTextBox("获取版本信息失败");
                return false;
            }

            if (string.IsNullOrEmpty(keyWps) == false)//移动、联通版本测试WPS按钮
            {
                //重试20次
                for (int i = 0; i < 25; i++)
                {
                    //ret = tel.GetReturnMsg(keywifi, out msg);
                    ret = tel.SendAndRecv(null, keyWps, out string msg);

                    AppendRichTextBox(msg);

                    if (ret) break;
                }


                if (ret)
                {
                    AppendRichTextBox("WPS按钮测试成功");
                    return true;
                }
                else
                {
                    AppendRichTextBox("WPS按钮测试失败");
                    return false;
                }
            }

            return true;//电信返回true
        }

        /// <summary>
        /// 写R方案的信息
        /// </summary>
        /// <param name="deviceData"></param>
        /// <returns></returns>
        private bool WriteDeviceDataR(Device_Data deviceData, Device_Type deviceType, YcdTelnetSecond tel)
        {

            tel.SendAndRecv("flash get HW_LIGHT_MODEL", "HW_LIGHT_MODEL=", out string msg);

            msg = msg.Replace("\r", "").Replace("\n", "");
            if (string.IsNullOrEmpty(msg) || msg.LastIndexOf("=") >= msg.Length - 4)
            {
                //清除产测区
                var clearResult = TelnetSendAndRecv(tel, "default_hsnw", "reserve_critical");
                if (clearResult == false) { SetResultOne("清除产测区失败", false); return false; }
                else { SetResultOne("清除产测区成功", true); }
            }

            bool speed = YcdTelnetMethod.CheckPortSpeed(tel, out msg);

            AppendRichTextBox(msg);
            //AppendRichTextBox(msg2);

            if (speed == false)
            {
                SetResultOne("网口速度不正常", false);
                return false;
            }
            else
            {
                SetResultOne("网口速度正常", true);
            }
            if (_cmdChoice == "4")
            {
                tel.SendAndRecv("flash set MIB_HW_BOSA_TYPE_NAME ATX_APGB122DP2AHS_PT927", "#", out msg);
                AppendRichTextBox(msg);
            }

            //XPON型号
            string ponMode = null;
            if (deviceData.PONType == "STIA")
            {
                ponMode = "1";
                //写BOB信息
                if (_cmdChoice == "3")
                    tel.Send("prolinecmd bobinfo UX GPON write 0 &\r\n");
                else if (_cmdChoice == "0")
                    TelnetSendAndRecv(tel, "prolinecmd bobinfo UX GPON ALPHA write 0 &", "Command received");
                else if (_cmdChoice == "1")
                    TelnetSendAndRecv(tel, "prolinecmd bobinfo UX GPON APD write 0 &", "Command received");
                else if (_cmdChoice == "2")
                    TelnetSendAndRecv(tel, "prolinecmd bobinfo UX GPON ATX write 0 &", "Command received");
            }
            else
            {
                ponMode = "2";
                //写BOB初始化信息
                if (_cmdChoice == "3")
                    tel.Send("prolinecmd bobinfo UX EPON write 0 &\r\n");
                else if (_cmdChoice == "0")
                    TelnetSendAndRecv(tel, "prolinecmd bobinfo UX EPON ALPHA write 0 &", "Command received");
                else if (_cmdChoice == "1")
                    TelnetSendAndRecv(tel, "prolinecmd bobinfo UX EPON APD write 0 &", "Command received");
                else if (_cmdChoice == "2")
                    TelnetSendAndRecv(tel, "prolinecmd bobinfo UX EPON ATX write 0 &", "Command received");
            }

            //注销日期：2018.8.21尝试是否可以在不写这些信息的情况下，运行BOB、WIFI校准等工序
            /**/
            //设备序列号
            var writeResult = TelnetSendAndRecv(tel, string.Format("flash set HW_SERIAL_NO {0}", deviceData.OUI2), "=" + deviceData.OUI2);
            if (writeResult == false) { SetResultOne("写设备序列号失败", false); return false; }
            else { SetResultOne("写设备序列号成功", true); }

            //设备型号
            string type = deviceData.DeviceType.Replace(" ", "");
            if (type.Contains("_"))
            {
                type = type.Substring(0, type.IndexOf("_"));
            }

            //writeResult = TelnetSendAndRecv(tel, string.Format("flash set HW_CWMP_PRODUCTCLASS {0}", type), "=" + type);
            //if (writeResult == false) { SetResultOne("写设备型号失败", false); return false; }
            //else { SetResultOne("写设备型号成功", true); }
            /**/

            writeResult = TelnetSendAndRecv(tel, string.Format("flash set PON_MODE {0}", ponMode), "=" + ponMode);
            if (writeResult == false) { SetResultOne("写PON的型号失败", false); return false; }
            else { SetResultOne("写PON的型号成功", true); }

            /*注销2018.8.218*/
            //硬件版本
            writeResult = TelnetSendAndRecv(tel, string.Format("flash set HW_HWVER {0}", deviceType.HWVersion), "=" + deviceType.HWVersion);
            if (writeResult == false) { SetResultOne("写设备硬件版本失败", false); return false; }
            else { SetResultOne("写设备硬件版本成功", true); }

            //普通用户密码
            //writeResult = WriteAndReadMsg(tel, string.Format("flash set DEFAULT_USER_PASSWORD {0}", deviceData.WedPassword), "flash get DEFAULT_USER_PASSWORD", "=" + deviceData.WedPassword, "=" + deviceData.WedPassword);
            writeResult = TelnetSendAndRecv(tel, string.Format("flash set DEFAULT_USER_PASSWORD {0}", deviceData.WedPassword), "=" + deviceData.WedPassword);
            if (writeResult == false) { SetResultOne("写普通用户密码失败", false); return false; }
            else { SetResultOne("写普通用户密码成功", true); }

            //无线名称
            //writeResult = WriteAndReadMsg(tel, string.Format("flash set DEFAULT_WLAN_SSID {0}", deviceData.WIFI_SSID), "flash get DEFAULT_WLAN_SSID", "=" + deviceData.WIFI_SSID, "=" + deviceData.WIFI_SSID);
            writeResult = TelnetSendAndRecv(tel, string.Format("flash set DEFAULT_WLAN_SSID {0}", deviceData.WIFI_SSID), "=" + deviceData.WIFI_SSID);
            if (writeResult == false) { SetResultOne("写WIFI名称失败", false); return false; }
            else { SetResultOne("写WIFI名称成功", true); }

            //无线密钥
            //writeResult = WriteAndReadMsg(tel, string.Format("flash set DEFAULT_WLAN_WPAKEY {0}", deviceData.WIFI_Password), "flash get DEFAULT_WLAN_WPAKEY", "=" + deviceData.WIFI_Password, "=" + deviceData.WIFI_Password);
            writeResult = TelnetSendAndRecv(tel, string.Format("flash set DEFAULT_WLAN_WPAKEY {0}", deviceData.WIFI_Password), "=" + deviceData.WIFI_Password);
            if (writeResult == false) { SetResultOne("写WIFI密码失败", false); return false; }
            else { SetResultOne("写WIFI密码成功", true); }


            //光模块型号
            //writeResult = WriteAndReadMsg(tel, string.Format("flash set HW_LIGHT_MODEL {0}", deviceData.LightModule), "flash get HW_LIGHT_MODEL", "=" + deviceData.LightModule, "=" + deviceData.LightModule);
            writeResult = TelnetSendAndRecv(tel, string.Format("flash set HW_LIGHT_MODEL {0}", deviceData.ProductCode), "=" + deviceData.ProductCode);
            if (writeResult == false) { SetResultOne("写光模块型号失败", false); return false; }
            else { SetResultOne("写光模块型号成功", true); }

            //光模块序列号
            writeResult = WriteAndReadMsg(tel, string.Format("flash set HW_LIGHT_SN {0}", deviceData.LightModuleSN), "flash get HW_LIGHT_SN", "=" + deviceData.LightModuleSN, "=" + deviceData.LightModuleSN);
            writeResult = TelnetSendAndRecv(tel, string.Format("flash set HW_LIGHT_SN {0}", deviceData.LightModuleSN), "=" + deviceData.LightModuleSN);
            if (writeResult == false) { SetResultOne("写光模块序列号失败", false); return false; }
            else { SetResultOne("写光模块序列号成功", true); }

            //GPON_SN，只有GPON才写SN号码
            if (deviceData.PONType == "STIA")
            {
                if (string.IsNullOrEmpty(_defaultSn) == false && _defaultSn != "000000000000")//为兼容最新的跑流思路，这么做！写固定的SN号码
                {
                    deviceData.XPON_SN = _defaultSn;
                }

                writeResult = TelnetSendAndRecv(tel, string.Format("flash set GPON_SN {0}", deviceData.XPON_SN), "=" + deviceData.XPON_SN);
                if (writeResult == false) { SetResultOne("写GPON_SN失败", false); return false; }
                else { SetResultOne("写GPON_SN成功", true); }
            }

            //厂商名称
            //string companyName = "youhua";
            writeResult = TelnetSendAndRecv(tel, string.Format("flash set HW_CWMP_MANUFACTURER {0}", deviceType.Manufacturer), "=" + deviceType.Manufacturer);
            if (writeResult == false) { SetResultOne("写厂商名称失败", false); return false; }
            else { SetResultOne("写厂商名称成功", true); }

            //版本校验码key
            //writeResult = WriteAndReadMsg(tel, string.Format("flash set HW_CIPHER {0}", deviceData.HW_CIPHER), "flash get HW_CIPHER", "=" + deviceData.HW_CIPHER, "=" + deviceData.HW_CIPHER);
            writeResult = TelnetSendAndRecv(tel, string.Format("flash set HW_CIPHER {0}", "uAfTzNQyLuVFcbJqpxUuzVUoe52ihzswGDHrZ4WKC1p31BEQPpMu/rkyt0zoatwiFrOA9CzNbhgmUbJZeZ8MFNzAnrUF2Av8qjNLnv21PUuaGvyNLlsANviZwOTydeF+5yP55AKeurp2AhfbpQBQJVuHibXOQgI0NMw+VjA0UfsA"), "=uAfTzNQyLuVFcbJqpxUuzVUoe52ihzswGDHrZ4WKC1p31BEQPpMu/rkyt0zoatwiFrOA9CzNbhgmUbJZeZ8MFNzAnrUF2Av8qjNLnv21PUuaGvyNLlsANviZwOTydeF+5yP55AKeurp2AhfbpQBQJVuHibXOQgI0NMw+VjA0UfsA");
            if (writeResult == false) { SetResultOne("写版本校验码KEY失败", false); return false; }
            else { SetResultOne("写版本校验码KEY成功", true); }

            ////软件版本校验码copyright
            writeResult = TelnetSendAndRecv(tel, string.Format("flash set HW_COPYRIGHT {0}", deviceType.HWCopyright), "=" + deviceType.HWCopyright);
            if (writeResult == false) { SetResultOne("写软件版本校验码copyright失败", false); return false; }
            else { SetResultOne("写软件版本校验码copyright成功", true); }

            ////写省份信息
            //writeResult = TelnetSendAndRecv(tel, string.Format("flash set HW_PROVINCE_NAME {0}", deviceData.HW_PROVINCE_NAME), "=" + deviceData.HW_PROVINCE_NAME);
            //if (writeResult == false) { SetResultOne("写省份信息失败", false); return false; }
            //else { SetResultOne("写省份信息成功", true); }

            /**/
            //关闭常发光指令
            writeResult = TelnetSendAndRecv(tel, "flash set USER_FACTORY_BEFORE_RUN 0", "USER_FACTORY_BEFORE_RUN=");
            if (writeResult == false) { SetResultOne("关闭常发光失败", false); return false; }
            else { SetResultOne("关闭常发光成功", true); }

            writeResult = TestButton(tel);
            if (writeResult == false) { SetResultOne("按键失败", false); return false; }
            else { SetResultOne("按键成功", true); }

            //MAC烧录
            //writeResult = WriteAndReadMsg(tel, string.Format("flash set ELAN_MAC_ADDR {0}", deviceData.MACAddr), "flash get ELAN_MAC_ADDR", "="+deviceData.MACAddr, "=" + deviceData.MACAddr);
            writeResult = TelnetSendAndRecv(tel, string.Format("flash set ELAN_MAC_ADDR {0}", deviceData.MACAddr), "=" + deviceData.MACAddr);
            if (writeResult == false) { SetResultOne("写MAC地址失败", false); return false; }
            else { SetResultOne("写MAC地址成功", true); }

            TelnetSendAndRecv(tel, "mpctl led on", "#");

            return true;
        }


        /// <summary>
        /// 写MTK方案的信息
        /// </summary>
        /// <param name="deviceData"></param>
        /// <returns></returns>
        private bool WriteDeviceDataMtk(Device_Data deviceData, Device_Type deviceType, YcdTelnetSecond tel)
        {
            //清除区域指令
            var writeResult = WriteAndReadMsg(tel, "prolinecmd clear 1", null, "write", null);
            if (writeResult == false) { SetResultOne("清除区域指令失败", false); return false; }
            else { SetResultOne("清除区域指令成功", true); }

            //写MAC
            writeResult = WriteAndReadMsg(tel, string.Format("sys mac {0} -n", deviceData.MACAddr), null, "addr", null);
            if (writeResult == false) { SetResultOne("写MAC地址失败", false); return false; }
            else { SetResultOne("写MAC地址成功", true); }

            //写productclass
            writeResult = WriteAndReadMsg(tel
                , string.Format("prolinecmd productclass set {0}", deviceData.DeviceType.Replace(" ", ""))
                , "prolinecmd productclass display"
                , "readflash"
                , deviceData.DeviceType.Replace(" ", ""));

            if (writeResult == false) { SetResultOne("写Productclass失败", false); return false; }
            else
            {
                SetResultOne("写Productclass成功", true);
            }
            //写oui1
            writeResult = WriteAndReadMsg(tel
                , string.Format("prolinecmd manufacturerOUI set  {0}", deviceData.OUI1)
                , "prolinecmd manufacturerOUI display"
                , "readflash"
                , deviceData.OUI1);

            if (writeResult == false) { SetResultOne("写OUI1失败", false); return false; }
            else { SetResultOne("写OUI1成功", true); }
            //写oui2
            writeResult = WriteAndReadMsg(tel
                , string.Format("prolinecmd serialnum set  {0}", deviceData.OUI2)
                , "prolinecmd serialnum display"
                , "readflash"
                , deviceData.OUI2);

            if (writeResult == false) { SetResultOne("写OUI2失败", false); return false; }
            else { SetResultOne("写OUI2成功", true); }
            //写硬件版本信息
            writeResult = WriteAndReadMsg(tel
                , string.Format("prolinecmd hwver set  {0}", deviceType.HWVersion)
                , "prolinecmd hwver display"
                , "readflash"
                , deviceType.HWVersion);

            if (writeResult == false) { SetResultOne("写硬件版本失败", false); return false; }
            else { SetResultOne("写硬件版本成功", true); }
            //校验软件版本信息
            writeResult = WriteAndReadMsg(tel
                , null
                , "cat /etc/swver"
                , null
                , deviceType.SWVersion);

            if (writeResult == false) { SetResultOne("检查软件版本失败", false); return false; }
            else { SetResultOne("检查软件版本成功", true); }
            //校验软件编译时间
            writeResult = WriteAndReadMsg(tel
                , null
                , "cat /etc/swver"
                , null
                , deviceType.BuildTime);

            if (writeResult == false) { SetResultOne("校验编译时间失败", false); return false; }
            else { SetResultOne("校验编译时间成功", true); }
            //写光模块SN
            writeResult = WriteAndReadMsg(tel
                , string.Format("prolinecmd lightmodulesn set {0}", deviceData.LightModuleSN)
                , "prolinecmd lightmodulesn display"
                , "readflash"
                , deviceData.LightModuleSN);

            if (writeResult == false) { SetResultOne("写光模块SN失败", false); return false; }
            else { SetResultOne("写光模块SN成功", true); }
            //写光模块型号
            writeResult = WriteAndReadMsg(tel
                , string.Format("prolinecmd lightmodule set {0}", deviceData.ProductCode)
                , "prolinecmd lightmodule display"
                , "readflash"
                , deviceData.ProductCode);

            if (writeResult == false) { SetResultOne("写光模块型号失败", false); return false; }
            else { SetResultOne("写光模块型号成功", true); }
            //写WIFI SSID
            writeResult = WriteAndReadMsg(tel
                , string.Format("prolinecmd ssid  set {0}", deviceData.WIFI_SSID)
                , "prolinecmd ssid  display"
                , "readflash"
                , deviceData.WIFI_SSID);

            if (writeResult == false) { SetResultOne("写wifi ssid失败", false); return false; }
            else { SetResultOne("写WiFi ssid成功", true); }
            //写WIFI密码
            writeResult = WriteAndReadMsg(tel
                , string.Format("prolinecmd wpakey  set {0}", deviceData.WIFI_Password)
                , "prolinecmd wpakey  display"
                , "readflash"
                , deviceData.WIFI_Password);

            if (writeResult == false) { SetResultOne("写WiFi密码失败", false); return false; }
            else { SetResultOne("写wifi密码成功", true); }
            //写ITVSSID
            writeResult = WriteAndReadMsg(tel
                , string.Format("prolinecmd ssid2nd  set {0}", deviceData.ITV_SSID)
                , "prolinecmd ssid2nd   display"
                , "readflash"
                , deviceData.ITV_SSID);

            if (writeResult == false) { SetResultOne("写ITV SSID失败", false); return false; }
            else { SetResultOne("写ITV SSID 成功", true); }
            //写ITV密码
            writeResult = WriteAndReadMsg(tel
                , string.Format("prolinecmd wpakey2nd  set {0}", deviceData.ITV_Password)
                , "prolinecmd wpakey2nd   display"
                , "readflash"
                , deviceData.ITV_Password);

            if (writeResult == false) { SetResultOne("写ITV 密码失败", false); return false; }
            else { SetResultOne("写ITV密码成功", true); }
            //写web用户名
            writeResult = WriteAndReadMsg(tel
                , string.Format("prolinecmd webAccount  set {0}", deviceData.WedUser)
                , "prolinecmd webAccount   display"
                , "readflash"
                , deviceData.WedUser);

            if (writeResult == false) { SetResultOne("写web用户名称失败", false); return false; }
            else { SetResultOne("写web用户名称成功", true); }
            //写web密码
            writeResult = WriteAndReadMsg(tel
                , string.Format("prolinecmd webpwd set {0}", deviceData.WedPassword)
                , "prolinecmd webpwd  display"
                , "readflash"
                , deviceData.WedPassword);

            if (writeResult == false) { SetResultOne("写web密码失败", false); return false; }
            else { SetResultOne("写web密码成功", true); }
            //写XPON modem
            writeResult = WriteAndReadMsg(tel
                , string.Format("prolinecmd xponmode set {0}", deviceType.XPONMode)
                , "prolinecmd xponmode display"
                , "readflash"
                , deviceType.XPONMode);

            if (writeResult == false) { SetResultOne("写XPON MODEM失败", false); return false; }
            else { SetResultOne("写XPON MODEM成功", true); }
            //写XPON SN
            writeResult = WriteAndReadMsg(tel
                , string.Format("prolinecmd xponsn set {0}", deviceData.XPON_SN)
                , "prolinecmd xponsn display"
                , "readflash"
                , deviceData.XPON_SN);

            if (writeResult == false) { SetResultOne("写XPON_SN失败", false); return false; }
            else { SetResultOne("写XPON_SN成功", true); }

            //关闭常发光指令
            writeResult = WriteAndReadMsg(tel, "echo dis_patter >/proc/pon_phy/debug", "tcapi set Autoexec_Entry cmd2 \"\"", "#", "#");
            var result2 = WriteAndReadMsg(tel, "tcapi set Autoexec_Entry cmd3 \"\"", "tcapi save", "#", "#");

            if (writeResult && result2)
            {
                SetResultOne("关闭长发光成功", true);
            }
            else
            {
                SetResultOne("关闭长发光失败", false);
                return false;
            }

            return true;
        }

        /// <summary>
        /// TELNET命令
        /// </summary>
        /// <param name="tel"></param>
        /// <param name="cmdStr"></param>
        /// <param name="keyWord"></param>
        /// <returns></returns>
        private bool TelnetSendAndRecv(YcdTelnetSecond tel, string cmdStr, string keyWord)
        {
            if (tel == null || tel.Connected == false || string.IsNullOrEmpty(cmdStr) || string.IsNullOrEmpty(keyWord)) return false;

            //tel.Send(cmdStr);

            string msg;

            //bool ret = tel.GetReturnMsg(keyWord, out msg);

            bool ret = tel.SendAndRecv(cmdStr, keyWord, out msg,6000);

            AppendRichTextBox(msg);

            return ret;
        }

        //写信息和回显信息，MTK和R通用
        private bool WriteAndReadMsg(YcdTelnetSecond tel, string writeCmd, string readCmd, string keyWordWrite, string keyWordRead)
        {
            if (string.IsNullOrEmpty(writeCmd) && string.IsNullOrEmpty(readCmd)) return false;

            if (tel.Connected == false) return false;

            //写信息
            if (string.IsNullOrEmpty(writeCmd) == false)
            {
                //tel.Send(writeCmd);

                string value;
                //bool hasKey = tel.GetReturnMsg(keyWordWrite.Trim(), out value);

                bool hasKey = tel.SendAndRecv(writeCmd, keyWordWrite, out value);

                if (hasKey == false) return false;
                //写LOG
                //WriteLog(value);
                AppendRichTextBox(value);
            }

            //只写，不读取
            readCmd = null;

            //读取信息
            if (string.IsNullOrEmpty(readCmd) == false)
            {
                //tel.Send(readCmd);

                string value;
                //bool hasKey = tel.GetReturnMsg(keyWordRead.Trim(), out value);
                bool hasKey = tel.SendAndRecv(readCmd, keyWordRead.Trim(), out value);
                if (hasKey == false) return false;

                //写log
                //WriteLog(value);
                AppendRichTextBox(value);
            }

            return true;
        }

        private int _portOffset = DateTime.Now.Second;

        /// <summary>
        /// 连接并登陆光猫，返回类，若为空则链接失败
        /// </summary>
        /// <returns></returns>
        private YcdTelnetSecond TelnetModem()
        {
            //使用新的类YcdTelnetSecond
            if (_portOffset >= 500) _portOffset = 0;
            _portOffset++;

            YcdTelnetSecond telnet = new YcdTelnetSecond(_modemIp, _localIp, _localPort + _portOffset);
            if (telnet.Connect() == false)
            {
                return null;
            }

            string msg;

            bool telRet = false;

            if (telnet.SendAndRecv(null, "login", out msg))
            {
                AppendRichTextBox("输入用户名称……");
                if (telnet.SendAndRecv(_modemUser, "password", out msg))
                {
                    AppendRichTextBox("输入用户密码……");
                    if (telnet.SendAndRecv(_modemPwd, "#", out msg))
                    {
                        AppendRichTextBox("登录成功");
                        telRet = true;
                    }
                }
            }

            if (telRet == false) { AppendRichTextBox("登录失败"); return null; }

            AppendRichTextBox(msg);

            return telnet;
        }

        /// <summary>
        /// 获取产品类型信息
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        private Device_Type GetDeviceType(string type, string province)
        {
            var device = (from t in _listType
                          where t.DeviceType == type && t.PROVINCE == province
                          select t).FirstOrDefault();

            return device;
        }



        //定位到mac输入位置，重置信息
        private void MacFocus(bool ifFocus = false)
        {
            if (this.textBoxMacAddr.InvokeRequired)
            {
                Action<bool> d = new Action<bool>(MacFocus);
                Invoke(d, ifFocus);
            }
            else
            {
                //清除list中的mac信息
                lock (PublicData.LOCKOBJUI)
                {
                    this.textBoxMacAddr.Clear();
                    this.textBoxXponSn.Clear();
                    if (ifFocus)
                        this.textBoxXponSn.Focus();
                }
            }
        }

        //设置textBox是否能够使用
        private void SetTextBoxReadOnly(TextBox box, bool read = false)
        {
            if (this.textBoxMacAddr.InvokeRequired)
            {
                Action<TextBox, bool> d = new Action<TextBox, bool>(SetTextBoxReadOnly);
                Invoke(d, box, read);
            }
            else
            {
                lock (PublicData.LOCKOBJUI)
                    box.ReadOnly = read;
            }
        }

        //将信息写入信息窗口
        private void AppendRichTextBox(string value)
        {
            if (this.richTextBoxMsg.InvokeRequired)
            {
                Action<string> d = new Action<string>(AppendRichTextBox);
                Invoke(d, new object[] { value });
            }
            else
            {
                if (string.IsNullOrEmpty(value)) return;
                //if (this.richTextBoxMsg.TextLength >= 5000)
                //    lock (PublicData.LOCKOBJUI)
                //        this.richTextBoxMsg.Clear();

                value = value.Replace("\0", "");

                lock (PublicData.LOCKOBJUI)
                    this.richTextBoxMsg.AppendText(value + "\r\n");

                WriteLog(value);
            }
        }

        private void ClearText(Control con)
        {
            if (this.InvokeRequired)
            {
                Action<Control> d = new Action<Control>(ClearText);
                Invoke(d, con);
            }
            else
            {
                lock (PublicData.LOCKOBJUI)
                    con.Text = null;
            }
        }

        private void SetControlText(Control con, string text, Color color)
        {
            if (this.InvokeRequired)
            {
                Action<Control, string, Color> d = new Action<Control, string, Color>(SetControlText);
                Invoke(d, con, text, color);
            }
            else
            {
                lock (PublicData.LOCKOBJUI)
                {
                    con.ForeColor = color;
                    if (string.IsNullOrEmpty(text) == false)
                        con.Text = text;
                }
            }
        }

        //设置结果
        //private void SetTestResult(bool result, string msg = null)
        //{
        //    if (labelTestResult.InvokeRequired)
        //    {
        //        Action<bool, string> d = new Action<bool, string>(SetTestResult);
        //        Invoke(d, result, msg);
        //    }
        //    else
        //    {
        //        if (result && msg == null)
        //        {
        //            this.labelTestResult.ForeColor = Color.Green;
        //            this.labelTestResult.Text = "PASS";
        //        }
        //        else if (result == false && msg == null)
        //        {
        //            this.labelTestResult.ForeColor = Color.Red;
        //            this.labelTestResult.Text = "FAIL";
        //        }
        //        else if (msg != null && result == false)
        //        {
        //            this.labelTestResult.ForeColor = Color.Black;
        //            this.labelTestResult.Text = msg;
        //        }
        //        else if (msg != null && result)
        //        {
        //            this.labelTestResult.ForeColor = Color.BlueViolet;
        //            this.labelTestResult.Text = msg;
        //        }
        //    }
        //}

        private void SetFocusXponSn()
        {
            if (this.textBoxXponSn.InvokeRequired)
            {
                Action d = new Action(SetFocusXponSn);
                Invoke(d);
            }
            else
            {
                lock (PublicData.LOCKOBJUI)
                    this.textBoxXponSn.Focus();
            }
        }

        /// <summary>
        /// 写log信息
        /// </summary>
        /// <param name="msg"></param>
        private void WriteLog(string msg)
        {
            _listLog.Add(msg);
        }

        /// <summary>
        /// 一个信息写入结束时操作
        /// </summary>
        private void FinallyDone(string xponSn = null, bool result = false, string state = null)
        {
            if (xponSn != null)//有一种情况不情况对应的xponSN
                PublicData.ListAddress.Remove(xponSn);


            Color colorText = Color.Black; //颜色
            string showText = state;//显示内容

            //修改显示内容
            if (result == false) { showText = "FAIL"; colorText = Color.Red; }
            else if (state == "E") { showText = "PASS"; colorText = Color.BlueViolet; }
            else if (state == "G") { showText = "PASS"; colorText = Color.Green; }

            //显示内容
            SetControlText(this.labelTestResult, showText, colorText);

            //判断光猫是否已经拔出了，如果拔出了，显示等待中
            while (true)
            {
                bool linkStatus = PingBaseClass.PingTest(_localIp, _modemIp);/*ArpBaseClass.IsIpEnabled(_localIp);*/
                if (linkStatus == false)
                    break;//没有连接，直接结束

                Thread.Sleep(500);
            }

            //SetTestResult(false, "WAIT");
            SetControlText(this.labelTestResult, "WAIT", Color.Black);

            //SetTextBoxReadOnly(textBoxXponSn, false);//设置textbox可用

            MacFocus();//清空mac/sns
        }

        private void richTextBoxMsg_TextChanged(object sender, EventArgs e)
        {
            lock (PublicData.LOCKOBJUI)
            {
                richTextBoxMsg.SelectionStart = richTextBoxMsg.Text.Length;
                richTextBoxMsg.ScrollToCaret();
            }
        }

        //写单项结果
        private void SetResultOne(string msg, bool result)
        {
            if (this.labelResultOne.InvokeRequired)
            {
                //return;

                Action<string, bool> d = new Action<string, bool>(SetResultOne);
                Invoke(d, msg, result);
            }
            else
            {
                lock (PublicData.LOCKOBJUI)
                {
                    this.labelResultOne.Text = msg;
                    if (result) this.labelResultOne.ForeColor = Color.Green;
                    else this.labelResultOne.ForeColor = Color.Red;
                }
                WriteLog(msg);
            }
        }
    }
}
